/* waitdemo_multiple.c - Demonstrates how parent handles multiple child processes using waitpid and bit operations */  

#include <stdio.h>      // 标准输入输出头文件，用于 printf 和 perror  
#include <stdlib.h>     // 标准库头文件，用于 exit 和 EXIT_SUCCESS/EXIT_FAILURE  
#include <unistd.h>     // Unix 标准头文件，用于 fork 和 sleep  
#include <sys/types.h>  // 定义 pid_t  
#include <sys/wait.h>   // 提供 waitpid 和相关宏  

#define NUM_CHILDREN 3    // 子进程数量  
#define DELAY_BASE 2      // 基础休眠时间（秒）  

// 函数声明  
void child_code(int delay, int child_num);  
void parent_code(pid_t childpids[], int num_children);  

int main()  
{  
    pid_t childpids[NUM_CHILDREN];    // 用于存储子进程的 PID  
    int i;  

    // 创建多个子进程  
    for (i = 0; i < NUM_CHILDREN; i++) {  
        childpids[i] = fork();  
        if (childpids[i] == -1) {  
            perror("fork");  
            exit(EXIT_FAILURE);  
        }  
        else if (childpids[i] == 0) {  
            // 子进程执行代码  
            child_code(DELAY_BASE + i, i + 1);  
        }  
        // 父进程继续循环，创建下一个子进程  
    }  

    // 父进程等待所有子进程结束  
    parent_code(childpids, NUM_CHILDREN);  

    return EXIT_SUCCESS;  
}  

/*  
 * 子进程代码：打印信息，休眠一定时间，然后退出  
 */  
void child_code(int delay, int child_num)  
{  
    printf("Child %d (PID %d) starting, will sleep for %d seconds\n", child_num, getpid(), delay);  
    sleep(delay);  // 子进程休眠  
    printf("Child %d (PID %d) finished, exiting\n", child_num, getpid());  
    exit(10 + child_num);  // 以不同状态码退出  
}  

/*  
 * 父进程代码：等待所有子进程结束，并解析退出状态  
 */  
void parent_code(pid_t childpids[], int num_children)  
{  
    int i;  
    pid_t wait_rv;  
    int child_status;  
    int high_8, low_7, bit_7;  

    for (i = 0; i < num_children; i++) {  
        // 调用 waitpid() 等待特定的子进程结束  
        wait_rv = waitpid(childpids[i], &child_status, 0);  
        if (wait_rv == -1) {  
            perror("waitpid failed");  
            continue;  
        }  

        // 打印等待结束的信息  
        printf("done waiting for %d. Waitpid returned: %d\n", childpids[i], wait_rv);  

        // 使用位运算解析子进程的退出状态  
        high_8 = (child_status & 0xFF00) >> 8; // 获取退出码（高 8 位）  
        low_7  = child_status & 0x007F;        // 获取信号号（低 7 位）  
        bit_7  = (child_status & 0x0080) ? 1 : 0; // 获取是否生成 core dump（第 7 位）  

        printf("status: exit=%d, sig=%d, core=%d\n", high_8, low_7, bit_7);  
    }  

    printf("All child processes have been handled.\n");  
}
